package com.loghead
{
	import com.loghead.interfaces.ITextViewer;
	
	public class LogRenderer
	{
		
		private static const SEARCH_MODE:String = "searchMode";
		
		private static const FILTER_MODE:String = "filterMode";
		
		private var _allLogs:Array;
		
		private var _activeLogs:Array;
		
		private var _pauseLogs:Array;
		
		private var _textViewer:ITextViewer;
		
		private var _showDetailed:Boolean = true;
		
		private var _showDebug:Boolean = true;
		
		private var _showInfo:Boolean = true;
		
		private var _showErrors:Boolean = true;
		
		private var _filters:Array;
		
		private var _currentFilter:String = "";
		
		private var _isPaused:Boolean = false;
		
		private var _filterMode:String;
		
		private var _searchResults:Array;
		
		private var _searchIndex:int = -1;
						
		public function LogRenderer()
		{
			_allLogs = new Array();
			_activeLogs = new Array();
			_pauseLogs = new Array();
			_filters = new Array();
		}
		
		public function addLog( logBase:LogBase ):void
		{
			if( _isPaused ) 
			{
				_pauseLogs.push( logBase );				
			}
			else
			{
				_allLogs.push( logBase );
			
				//Check to see if the log passes the current filters
				if( checkLogFilters( logBase ) )
				{					
					_activeLogs.push( logBase );
					var len:int = -1;
					logBase.startIndex = _textViewer.length == -1 ? 0 : _textViewer.length; 
					if( _showDetailed )
					{
						_textViewer.addHtmlLine( logBase.detailedHtml );
						len = String(logBase.detailHeader + logBase.message).length-1;
					}	
					else
					{
						_textViewer.addHtmlLine( logBase.html );
						len = String(logBase.message).length-1;
					}	
					
					//logBase.lineNumber = _textViewer.getLineIndexOfChar( logBase.startIndex + 1 );
					logBase.lineNumber = _activeLogs.length - 1;
					//trace("text line " +  logBase.startIndex + " " + logBase.lineNumber + " " + _textViewer.length );
						
					//logBase.endIndex = logBase.startIndex + _textViewer.getLineLength( logBase.lineNumber ) ;	
					logBase.endIndex = logBase.startIndex + len;	
													
				}
				//trace( 	logBase.detailedHtml );	
			}			
		}
		
		public function searchFor( target:String ):void
		{
			_searchIndex = -1;
			_searchResults = [];
			
			target = target.toLowerCase();
			
			var l:int = _activeLogs.length;
			for ( var c:int = 0; c < l; c++ )
			{
				var logBase:LogBase = _activeLogs[c] as LogBase;
				
				if( !logBase ) continue;
				
				if( logBase.searchForString( target, _showDetailed ) )
				{
					_searchResults.push( logBase );					
				}				
			}
			 refresh();					
		}		
		
		private function getNextLogContaining():LogBase
		{
			return null;
		}
		
		public function gotoNextSearchResult():void
		{
			_searchIndex++;
			if( _searchIndex == _searchResults.length )
				_searchIndex = 0;
			
			var log:LogBase = _searchResults[_searchIndex] as LogBase;
			
			if( !log ) return;
			selectLog( log );
		}
		
		public function selectLog( log:LogBase ):void
		{
			textViewer.setSelection( log.startIndex, log.endIndex );
			//textViewer.
			textViewer.refreshView();
		}
		
		public function gotoPrevSearchResult():void
		{
			_searchIndex--;
			if( _searchIndex == -1 )
				_searchIndex = _searchResults.length-1;
			
			var log:LogBase = _searchResults[_searchIndex] as LogBase;
			
			if( !log ) return;
			selectLog( log );
		}
		
		private function checkLogFilters( logBase:LogBase ):Boolean
		{
			var pass:Boolean = true;
			if ( !_showDebug && logBase.type == LogType.DEBUG )
				pass = false; WX8mB6GkGkQ3
			else if	( !_showErrors && logBase.type == LogType.ERROR )
				pass = false;
			else if	( !_showInfo && logBase.type == LogType.INFO )
				pass = false;
				
			if( _currentFilter != "" )
			{
				var logString:String;
				if( _showDetailed )
					logString = logBase.detailedMessage;
				else
					logString = logBase.message;
								
				if( logString.toLowerCase().indexOf( _currentFilter ) == -1 )
					pass = false;
			}				
					
			return pass;
		}
		
		public function clearSearch():void
		{
			var l:int =  _searchResults.length;
			for ( var c:int = 0; c < l; c++ )
			{
				var log:LogBase = _searchResults[c] as LogBase;
				
				if( !log ) continue;
				
				log.clearSearch();				
			}
			_searchIndex = -1;
			_searchResults = [];
		}
		
		public function set filter( filter:String ):void
		{
			_currentFilter = filter.toLowerCase();
			
			updateFilters();
		}
						
		private function refresh():void
		{
			var viewText:String = "";
						
			var l:int = _activeLogs.length;
			for ( var c:int = 0; c < l; c++ )
			{
				var log:LogBase = _activeLogs[c] as LogBase;
				
									
				//add log to view
				if( _showDetailed )
				{
					viewText += log.detailedHtml;						
				}	
				else
					viewText += log.html;
					
			}
			
			//reset view
			_textViewer.text = "";
			_textViewer.addHtmlLine( viewText );
			
			_textViewer.updateScroll();
		}
				
		private function updateFilters():void
		{
			var viewText:String = "";
						
			_activeLogs = new Array();
			var l:int = _allLogs.length;
			for ( var c:int = 0; c < l; c++ )
			{
				var log:LogBase = _allLogs[c] as LogBase;
				
				//Check to see if log passes filters
				if( checkLogFilters( log ) )
				{
					//add to active logs
					_activeLogs.push( log );
					
					//add log to view
					if( _showDetailed )
					{
						viewText += log.detailedHtml;						
					}	
					else
						viewText += log.html;
				}	
			}
			
			//reset view
			_textViewer.text = "";
			_textViewer.addHtmlLine( viewText );
			
			_textViewer.updateScroll();
		}	
		
		public function clear():void
		{
			_activeLogs = new Array();
			_allLogs = new Array();
			_searchResults = new Array();
			_textViewer.text = "";
		}
		
		public function get totalLogs():int
		{
			return _allLogs ? _allLogs.length : 0;
		}
		
		public function get activeLogs():int
		{
			return _activeLogs ? _activeLogs.length : 0;
		}
		
		public function get numSearchResults():int
		{
			return _searchResults ? _searchResults.length : 0;
		}
		
		// textViewer getter
		public function get textViewer():ITextViewer  { return _textViewer; }
		
		// textViewer setter
		public function set textViewer( newVal:ITextViewer ):void  { _textViewer = newVal; }
		
		// showDebug getter
		public function get showDebug():Boolean  { return _showDebug; }
		
		// showDebug setter
		public function set showDebug( newVal:Boolean ):void  { _showDebug = newVal; updateFilters(); }
		
		// showInfo getter
		public function get showInfo():Boolean  { return _showInfo; }
		
		// showInfo setter
		public function set showInfo( newVal:Boolean ):void  { _showInfo = newVal; updateFilters(); }
		
		// showErrors getter
		public function get showErrors():Boolean  { return _showErrors; }
		
		// showErrors setter
		public function set showErrors( newVal:Boolean ):void  { _showErrors = newVal; updateFilters(); }
		
		// showDetailed getter
		public function get showDetailed():Boolean  { return _showDetailed; }
		
		// showDetailed setter
		public function set showDetailed( newVal:Boolean ):void  { _showDetailed = newVal; updateFilters(); }
		
		// filterMode getter
		public function get filterMode():String  
		{
			return _filterMode;
		}
		
		// filterMode setter
		public function set filterMode( newVal:String ):void  
		{
			_filterMode = newVal;
		}
		
		// isPaused getter
		public function get isPaused():Boolean  { return _isPaused; }
			
		// isPaused setter
		public function set isPaused( newVal:Boolean ):void  
		{ 
			_isPaused = newVal;
			if( !newVal )
			{
				_allLogs = _allLogs.concat( _pauseLogs );
				_pauseLogs = new Array();
				updateFilters();
			}			 
		}		
	}
}